home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
programr
/
makemdi2.zip
/
SHEET.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-25
|
15KB
|
483 lines
#define _SHEET_C
//-----------------------------------------------------------------
// SHEET.C - Sheet window management.
//
// MAKEMDI adaptation of Windows 3.1 SDK MAKEAPP system.
//
// MDI application design based on Chapter 7 of
// "Windows 3: A Developer's Guide" by Jeffrey Richter.
//
// Adaptation developed with permission of the author by
// John F. Holliday, Technisoft Corporation
// Telephone: (515) 472-9803, CompuServe: 71271,634
//
// [DMM] 25-Nov-1992: Fixed crashing on exit
// Also tabified file to tabsize of 4
//
// David M. Miller, Business Visions, Inc.
// Telephone: (212) 747-6118
// CompuServe: 72676,327
// internet: dmiller@hera.sbi.com
//-----------------------------------------------------------------
#include "makemdi.h"
BOOL Sheet_Initialize(APP * papp)
//-----------------------------------------------------------------
// Initialize all MDI child window classes.
//-----------------------------------------------------------------
{
WNDCLASS cls;
cls.hCursor = LoadCursor(NULL, IDC_ARROW);
cls.hIcon = NULL;
cls.lpszMenuName = NULL;
cls.hInstance = papp->hinst;
cls.lpszClassName = CLASS_SHEET;
cls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
cls.lpfnWndProc = Sheet_WndProc;
cls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
cls.cbWndExtra = sizeof(SHEET*);
cls.cbClsExtra = 0;
if (!RegisterClass(&cls))
return FALSE;
return TRUE;
}
void Sheet_Terminate(APP * papp)
{
}
LRESULT CALLBACK _export Sheet_WndProc(HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
SHEET *psheet = Sheet_GetPtr(hWnd);
if (psheet == NULL) {
if (msg == WM_NCCREATE) {
psheet = (SHEET *) LocalAlloc(
LMEM_FIXED | LMEM_ZEROINIT, sizeof(SHEET));
if (psheet == NULL)
return 0L;
psheet->hWnd = hWnd;
Sheet_SetPtr(hWnd, psheet);
}
else {
return Sheet_DefProc(hWnd, msg, wParam, lParam);
}
}
if (msg == WM_NCDESTROY) {
// DWORD result = HANDLE_MSG(hWnd, WM_NCDESTROY, Sheet_OnNCDestroy);
if (psheet->hMenu != NULL)
DestroyMenu(psheet->hMenu);
LocalFree((HLOCAL) OFFSETOF(psheet));
psheet = NULL;
Sheet_SetPtr(hWnd, NULL);
// return result;
}
switch (msg) {
HANDLE_MSG(psheet, WM_CREATE, Sheet_OnCreate);
HANDLE_MSG(psheet, WM_MDIACTIVATE, Sheet_OnMdiActivate);
HANDLE_MSG(psheet, WM_MOUSEACTIVATE, Sheet_OnMouseActivate);
HANDLE_MSG(psheet, WM_ENTERIDLE, Sheet_OnEnterIdle);
HANDLE_MSG(psheet, WM_MENUSELECT, Sheet_OnMenuSelect);
HANDLE_MSG(psheet, WM_SETCURSOR, Sheet_OnSetCursor);
HANDLE_MSG(psheet, WM_LBUTTONDOWN, Sheet_OnLButtonDown);
HANDLE_MSG(psheet, WM_CLOSE, Sheet_OnClose);
HANDLE_MSG(psheet, WM_DESTROY, Sheet_OnDestroy);
HANDLE_MSG(psheet, WM_PAINT, Sheet_OnPaint);
HANDLE_MSG(psheet, WM_ERASEBKGND, Sheet_OnEraseBkgnd);
HANDLE_MSG(psheet, WM_QUERYENDSESSION, Sheet_OnQueryEndSession);
HANDLE_MSG(psheet, WM_ENDSESSION, Sheet_OnEndSession);
HANDLE_MSG(psheet, WM_COMMAND, Sheet_OnCommand);
// Application messages.
HANDLE_MSG(psheet, AC_PAINTSTATBAR, Sheet_OnPaintStatBar);
HANDLE_MSG(psheet, AW_PAINTMENUHELP, Sheet_OnPaintMenuHelp);
default:
return Sheet_DefProc(hWnd, msg, wParam, lParam);
}
}
typedef struct {
LPCSTR lpszText;
COLORREF clrText;
}
SHEET_INIT;
HWND Sheet_CreateWindow(HWND hWndParent, int x, int y, int cx, int cy, BOOL fVisible, COLORREF clrText, LPCSTR lpszText)
{
SHEET_INIT init;
init.lpszText = lpszText;
init.clrText = clrText;
return CreateWindowEx(
0L, // extendedStyle
CLASS_SHEET, // class name
NULL, // text
(fVisible ? (WS_CHILD | WS_VISIBLE) : WS_CHILD),
x, y, cx, cy, // x, y, cx, cy
hWndParent,// hWndParent
NULL, // hmenu
g_app.hinst, // hInstance
&init); // lpCreateParams
}
BOOL Sheet_OnCreate(SHEET * psheet, CREATESTRUCT FAR * lpCreateStruct)
{
SHEET_INIT FAR *pinit = (SHEET_INIT FAR *) lpCreateStruct->lpCreateParams;
psheet->lpszText = pinit->lpszText;
psheet->clrText = pinit->clrText;
// If this window is first instance created of this class.
if (psheet->hMenu == NULL) {
// Initialize the menu and accelerator handles for this class.
psheet->hMenu = LoadMenu(g_app.hinst, MAKEINTRESOURCE(IDR_SHEETMENU));
psheet->hAccelTable = LoadAccelerators(g_app.hinst, MAKEINTRESOURCE(IDR_SHEETACCEL));
}
return TRUE;
}
void Sheet_OnMdiActivate(SHEET * psheet, BOOL fBeingActivated, HWND hWndChild, HWND hWndPrevChild)
{
if (fBeingActivated) {
// Child is being activated.
psheet->hWndPrevChild = hWndPrevChild;
// If this child is being activated and no other child exists,
// pretend that this child was the last activated child.
if (psheet->hWndPrevChild == NULL)
psheet->hWndPrevChild = psheet->hWnd;
// Set the menu bar and the accelerators to the appropriate ones
// for this window class.
Frame_ChangeMDIMenu(
GETFRAME(psheet->hWnd),
GetParent(psheet->hWnd),
psheet->hMenu,
CMD_WINDOWTILEVERT);
g_app.hAccelTable = psheet->hAccelTable;
// For the Status bar at the bottom of the Frame window to be
// updated for this child's information.
InvalidateRect(GETFRAME(psheet->hWnd), NULL, TRUE);
}
else {
// Child is being deactivated.
// Reset the previous child so WM_MOUSEACTIVATE will work Ok.
psheet->hWndPrevChild = NULL;
}
}
int Sheet_OnMouseActivate(SHEET * psheet, HWND hWndTopLevel, UINT codeHitTest, UINT msg)
//-----------------------------------------------------------------
// User clicked the mouse of the Child window.
// If the mouse is clicked in the window's client area and
// the previously active child was NOT this child, the
// mouse message should be eaten.
//-----------------------------------------------------------------
{
if ((codeHitTest == HTCLIENT) &&
(psheet->hWnd != psheet->hWndPrevChild))
return MA_ACTIVATEANDEAT;
return MA_ACTIVATE;
}
void Sheet_OnEnterIdle(SHEET * psheet, UINT source, HWND hWndSource)
//-----------------------------------------------------------------
// User stopped moving around in the help system, make the Frame
// believe that it received this message directly.
//-----------------------------------------------------------------
{
FORWARD_WM_ENTERIDLE(GETFRAME(psheet->hWnd), source, hWndSource, SendMessage);
}
void Sheet_OnMenuSelect(SHEET * psheet, HMENU hMenu, int item, HMENU hMenuPopup, UINT flags)
//-----------------------------------------------------------------
// Normally, only MDI Child system menu options could appear
// in this message. But the Frame window forces WM_MENUSELECT
// messages to appear here whenever a menu selection occurs.
//-----------------------------------------------------------------
{
WORD wTemp;
HMENU hMenuFrame;
if (flags == -1 && (hMenu == (HMENU) 0)) {
// User has stopped using the menu system. Notify Frame window
// so that the status bar will be invalidated.
SendMessage(GETFRAME(psheet->hWnd), FW_SETMENUHELP, 0, 0);
return;
}
switch (flags & (MF_POPUP | MF_SYSMENU)) {
case 0:
// Item is a menu item ID NOT on the Child's system menu.
// If item is any of the MDI Children listed in the
// "Window" menu, display the same help text.
if ((item > CMD_WINDOWCHILD) && (item <= CMD_WINDOWCHILD + 9))
item = CMD_WINDOWCHILD;
wTemp = IDS_SHEETMENUID + item;
break;
case MF_POPUP:
// Calculate the index of the top-level menu.
hMenuFrame = GetMenu(GETFRAME(psheet->hWnd));
wTemp = GetMenuItemCount(hMenuFrame);
while (wTemp--)
if (GetSubMenu(hMenuFrame, wTemp) == hMenuPopup)
break;
wTemp += IDS_SHEETPOPUPID;
if (!IsZoomed(psheet->hWnd))
wTemp++;
break;
case MF_SYSMENU:
// Item is menu item ID from MDI Child's system menu.
wTemp = IDS_SHEETMENUID + ((item & 0x0FFF) >> 4);
break;
case MF_POPUP | MF_SYSMENU:
// Item is handle to MDI Child's sys menu.
wTemp = IDS_SHEETPOPUPID;
break;
}
// Tell the Frame that this window should display the help
// text and the identifier for the help text.
SendMessage(GETFRAME(psheet->hWnd), FW_SETMENUHELP,
(WPARAM) psheet->hWnd, (LPARAM) wTemp);
}
BOOL Sheet_OnSetCursor(SHEET * psheet, HWND hWndCursor, UINT codeHitTest, UINT msg)
//-----------------------------------------------------------------
// After an MDI Child becomes active, set the previously active
// child to this window so that mouse messages will NOT be eaten.
//-----------------------------------------------------------------
{
psheet->hWndPrevChild = psheet->hWnd;
return FORWARD_WM_SETCURSOR(psheet->hWnd, hWndCursor, codeHitTest, msg, Sheet_DefProc);
}
void Sheet_OnLButtonDown(SHEET * psheet, BOOL fDoubleClick, int x, int y, UINT keyFlags)
//-----------------------------------------------------------------
// Just to let you know when the WM_LBUTTONDOWN message is received.
//-----------------------------------------------------------------
{
MessageBox(psheet->hWnd, "WM_LBUTTONDOWN", "Sheet", MB_OK);
}
void Sheet_OnClose(SHEET * psheet)
//-----------------------------------------------------------------
// Make sure that it is OK to close this child window.
//-----------------------------------------------------------------
{
if ((BOOL) SendMessage(psheet->hWnd, WM_QUERYENDSESSION, 0, 0)) {
SendMessage(psheet->hWnd, WM_ENDSESSION, TRUE, 0);
FORWARD_WM_CLOSE(psheet->hWnd, Sheet_DefProc);
}
}
void Sheet_OnDestroy(SHEET * psheet)
//-----------------------------------------------------------------
// Notify the Frame window that a child has been destroyed after
// the child is actually destroyed. (That's why we use
// PostMessage instead of SendMessage here).
//-----------------------------------------------------------------
{
PostMessage(GETFRAME(psheet->hWnd), FW_MDICHILDDESTROY, (WPARAM) psheet->hWnd, 0);
FORWARD_WM_DESTROY(psheet->hWnd, Sheet_DefProc);
}
void Sheet_OnPaint(SHEET * psheet)
//-----------------------------------------------------------------
//-----------------------------------------------------------------
{
PAINTSTRUCT ps;
HDC hdc;
RECT rc;
hdc = BeginPaint(psheet->hWnd, &ps);
GetClientRect(psheet->hWnd, &rc);
FillRect(hdc, &rc, GetStockBrush(WHITE_BRUSH));
InflateRect(&rc, -4, -4);
FrameRect(hdc, &rc, GetStockBrush(BLACK_BRUSH));
if (psheet->lpszText) {
int cch = lstrlen(psheet->lpszText);
int x;
int y;
SIZE size;
GetTextExtentPoint(hdc, psheet->lpszText, cch, &size);
x = rc.left + (rc.right - rc.left - size.cx) / 2;
y = rc.top + (rc.bottom - rc.top - size.cy) / 2;
SetTextColor(hdc, psheet->clrText);
TextOut(hdc, x, y, psheet->lpszText, cch);
}
EndPaint(psheet->hWnd, &ps);
}
BOOL Sheet_OnEraseBkgnd(SHEET * psheet, HDC hdc)
//-----------------------------------------------------------------
// Let DefWindowProc erase the background
//-----------------------------------------------------------------
{
return FORWARD_WM_ERASEBKGND(psheet->hWnd, hdc, DefWindowProc);
}
BOOL Sheet_OnQueryEndSession(SHEET * psheet)
//-----------------------------------------------------------------
//-----------------------------------------------------------------
{
WORD wTemp;
BOOL fOkToQuit = FALSE;
// Prompt user whether to save changes to this document.
// Usually, a dirty flag (stored in the window's extra bytes
// is used to determine if it is necessary to ask this question).
// Construct string including the document's name.
lstrcpy(g_app.szBuf, "Save changes to ");
wTemp = lstrlen(g_app.szBuf);
GetWindowText(psheet->hWnd, g_app.szBuf + wTemp,
sizeof(g_app.szBuf) - wTemp);
lstrcat(g_app.szBuf, "?");
// Display message box to user. The message box should
// be system modal if the entire Windows session is being
// terminated. (wParam is FALSE).
switch (
MessageBox(
psheet->hWnd,
g_app.szBuf,
g_app.szName,
MB_ICONQUESTION | MB_YESNOCANCEL |
MB_APPLMODAL)) {
case IDYES:
// Save the document and it's OK to quit.
fOkToQuit = TRUE;
break;
case IDNO:
// Don't save the document and it's OK to quit.
fOkToQuit = TRUE;
break;
}
return fOkToQuit;
}
void Sheet_OnEndSession(SHEET * psheet, BOOL fEnding)
//-----------------------------------------------------------------
// Do any last minute cleanup during this message.
//-----------------------------------------------------------------
{
}
void Sheet_OnCommand(SHEET * psheet, int id, HWND hWndCtl, UINT codeNotify)
//-----------------------------------------------------------------
// Any menu options NOT processed by the Frame are passed to the
// active child.
//-----------------------------------------------------------------
{
MessageBox(psheet->hWnd, "Option not implemented.", g_app.szName, MB_OK);
}
void Sheet_OnPaintStatBar(SHEET * psheet, HDC hdc, LPPAINTSTRUCT psStatus)
//-----------------------------------------------------------------
// Message sent by the Frame window when the status bar needs to
// be repainted.
//-----------------------------------------------------------------
{
// Construct status bar string for display.
LoadString(g_app.hinst, IDS_SHEETSTATUSBAR, g_app.szBuf, sizeof(g_app.szBuf));
// Draw the horizontal dividing line separating the Status bar
// from the MDICLIENT window.
psStatus->rcPaint.top += (int)
SendMessage(GETFRAME(psheet->hWnd), FW_DRAWSTATUSDIVIDE, 0,
(LPARAM) psStatus);
// Paint the text in the status bar.
TextOut(hdc, 0, psStatus->rcPaint.top, g_app.szBuf, lstrlen(g_app.szBuf));
}
void Sheet_OnPaintMenuHelp(SHEET * psheet, LPPAINTSTRUCT psStatus)
//-----------------------------------------------------------------
// Message sent from Frame window to notify child that it should
// paint the status bar text for the last highlighted menu item.
// lParam = LPPAINTSTRUCT of Frame's status bar.
//-----------------------------------------------------------------
{
LRESULT lResult;
// Ask the Frame window what the last selected menu ID was.
// This value was sent to the frame by this window during the
// processing for the WM_MENUSELECT message.
lResult = SendMessage(GETFRAME(psheet->hWnd), FW_GETMENUHELP, 0, 0);
// Draw the horizontal dividing line separating the Status bar
// from the MDICLIENT window.
psStatus->rcPaint.top += (int)
SendMessage(GETFRAME(psheet->hWnd), FW_DRAWSTATUSDIVIDE, 0,
(LPARAM) psStatus);
// Construct the string that is to be displayed.
LoadString(g_app.hinst, LOWORD(lResult), g_app.szFmt, sizeof(g_app.szFmt));
GetWindowText(psheet->hWnd, g_app.szCap, sizeof(g_app.szCap));
wsprintf(g_app.szBuf, g_app.szFmt, (LPSTR) g_app.szCap);
// Paint the menu help text in the status bar.
TextOut(psStatus->hdc,
0, psStatus->rcPaint.top, g_app.szBuf, lstrlen(g_app.szBuf));
}